import re

from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework.serializers import ModelSerializer
from rest_framework_jwt.settings import api_settings

from celery_tasks.email.tasks import send_active_email
from users.models import User, Address


class CreateUserSerializer(ModelSerializer):
    """
    创建用户使用的序列化器
    要校验的地租单
    要序列化返回的字段
    重写create,实现新增一个用户(注册)
    """
    password = serializers.CharField(label='密码',write_only=True)
    password2 = serializers.CharField(label='确认密码',write_only=True)
    sms_code = serializers.CharField(label='短信确认码',max_length=6,write_only=True)
    allow = serializers.BooleanField(label='同意用户协议',default=False,write_only=True)
    #注册成功之后,自动登录,需要生成返回jwt
    token = serializers.CharField(label='JWT',read_only=True)



    def create(self, validated_data):
        #创建一个用户对象
        #不能使用默认的实现
        # return super().create(validated_data)

        #User.objects.create()  #密码不会加密
        user = User.objects.create_user(
            username = validated_data.get('username'),
            password = validated_data.get('password'),
            mobile = validated_data.get('mobile'),
        )

        #todo:生成jwt
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER  #生成payload部分的方法
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER   #生成jwt的方法

        #{'exp':xxx,'email':'','user_id': 1, 'username':'admin'}
        #user:登录的用户对象

        payload = jwt_payload_handler(user)   #生成payload,得到字典
        token = jwt_encode_handler(payload)   #生成jwt字符串
        user.token = token

        return user

    class Meta:
        model = User
        fields = (
            'id', 'username', 'mobile', 'password', 'password2', 'sms_code', 'allow','token'
        )

        extra_kwargs = {
            'username': {
                'min_length': 5,
                'max_length': 20,
                'error_messages': {
                    'min_length': '仅允许5-20个字符的用户名',
                    'max_length': '仅允许5-20个字符的用户名',
                }
            },
            'password': {
                'write_only': True,
                'min_length': 8,
                'max_length': 20,
                'error_messages': {
                    'min_length': '仅允许8-20个字符的密码',
                    'max_length': '仅允许8-20个字符的密码',
                }
            }
        }


    def validate_mobile(self,value):
        """验证手机号"""
        if not re.match(r'^1[3-9]\d{9}$',value):
            raise serializers.ValidationError('手机号格式错误')
        return value

    def validate_allow(self,value):
        """检验用户是否同意协议"""
        if not value:
            raise serializers.ValidationError("请同意用户协议")
        return value


    # def validate(self,attrs):
    #     #判断两次密码
    #     if attrs['password'] != attrs['password2']:
    #         raise serializers.ValidationError('两次密码不一致')
    #         #return Response({message':'两次密码不一致'},status=400)
    #
    #
    #     #t todo:判断短信验证码是否正确
    #     #获取手机号
    #     mobile = attrs.get('mobile')
    #     #获取正确的短信验证码
    #     strict_redis  = get_redis_connection('sms_codes') #type:StrictRedis
    #     real_sms_code = strict_redis.get('sms_%s' % mobile) #bytes
    #     if not real_sms_code:
    #         raise ValidationError('短信验证码无效')

        #获取用户传递的验证码
        sms_code = attrs.get('sms_code')
        #判断是否相等
        if sms_code != real_sms_code.decode():
            raise ValidationError('短信验证码不正确')

        return attrs



class UserDetailSerializer(serializers.ModelSerializer):
    """用户详细信息序列化器"""
    class Meta:
        model = User
        fields = ('id','username','mobile','email','email_active')



class EmailSerializer(ModelSerializer):
    """修改用户:邮箱"""

    def update(self, instance, validated_data):
        #1.校验邮箱
        #2.修改邮箱


        #修改一条用户数据
        #instance其实是用户对象来的
        instance.email = validated_data['email']
        instance.save()

        #3.todo: 发送激活链接到用户的邮箱地址
        active_url = instance.generate_active_email()
        #使用celery发送邮件
        #参数1:接收者
        #参数2:激活链接
        send_active_email.delay(instance.email,active_url)

        return instance

    class Meta:
        model = User
        fields = ('id','email')
        extra_kwargs = {
            'email':{
                'required': True
            }
        }


class UserAddressSerializer(serializers.ModelSerializer):
    """
    用户地址序列化器
    """

    #序列时用到
    province = serializers.StringRelatedField(read_only=True)
    city = serializers.StringRelatedField(read_only=True)
    district = serializers.StringRelatedField(read_only=True)

    #新增地址时校验用到的:新增地址时补充的字段(可读可写)
    province_id = serializers.IntegerField(label='省ID', required=True)
    city_id = serializers.IntegerField(label='市ID', required=True)
    district_id = serializers.IntegerField(label='区ID', required=True)

    class Meta:
        model = Address
        exclude = ('user', 'is_deleted', 'create_time', 'update_time')

    def validate_mobile(self, value):
        """
        验证手机号
        """
        if not re.match(r'^1[3-9]\d{9}$', value):
            raise serializers.ValidationError('手机号格式错误')
        return value

    def create(self, validated_data):
        """
        保存
        """
        validated_data['user'] = self.context['request'].user
        return super().create(validated_data)


class AddressTitleSerializer(serializers.ModelSerializer):
    """
    地址标题
    """

    class Meta:
        model = Address
        fields = ('title',)
